/***********************************************************
* 
*     File Name:  main.h
* 
*        Author:  Algolc
* 
*          mail:  17360224@qq.com
* 
*  Created Time:  Wed 13 Jun 2018 03:11:12 PM CST
* 
***********************************************************/
#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <openssl/md5.h>
#include <sstream>
#include "json.h"
#include <iostream>
#include <cassert>

#define MAX(A, B) ((A) > (B) ? (A) : (B))

using namespace std;
const int DEFAULT_LINE = 10;
const int DEFAULT_TYPE_LINE = 17;
//urlencode转化
std::string UrlEncode(const std::string& szToEncode) {  
    std::string src = szToEncode;  
    char hex[] = "0123456789ABCDEF";  
    string dst;  
  
    for (size_t i = 0; i < src.size(); ++i) {  
        unsigned char cc = src[i];  
        if ( cc >= 'A' && cc <= 'Z'   
                 || cc >='a' && cc <= 'z'  
                 || cc >='0' && cc <= '9'  
                 || cc == '.'  
                 || cc == '_'  
                 || cc == '-'  
                 || cc == '*')  {
            if (cc == ' ') {  
                dst += "+";  
            }  else {
                dst += cc;  
            }
        } else {  
            unsigned char c = static_cast<unsigned char>(src[i]);  
            dst += '%';  
            dst += hex[c / 16];  
            dst += hex[c % 16];  
        }  
    }  
    return dst;  
}

class CTranCurl {
private:
    void GetNewSalt() {
        int rand_num = rand();
        ostringstream ss;
        ss << rand_num;
        salt = ss.str();
    }

    void SetSign() {
        ostringstream ss;
        ss << appid << q << salt << secret_key;
        sign = ss.str();
    }

    int GetSignMd5() {
        SetSign();
        MD5_CTX ctx;
        unsigned char md[16];
        int i;
        char tmp[3] = {""}, buf[33] = {""};

        MD5_Init(&ctx);
        MD5_Update(&ctx, (unsigned char*)sign.c_str(), sign.size());
        MD5_Final(md, &ctx);
        for (i = 0; i < 16; i++) {
            sprintf(tmp, "%2.2x", md[i]);
            strcat(buf, tmp);
        }
        md5_sign = buf;
    }

    int SetMyUrl() {
        q_encode = UrlEncode(q);
        ostringstream ss;
        ss << myurl << "&q=" << q_encode
            << "&from=" << from
            << "&to=" << to
            << "&appid=" << appid
            << "&salt=" << salt
            << "&sign=" << md5_sign;
        send_myurl = ss.str();
    }

public:
    CTranCurl() {
    }

    CTranCurl(std::string req_q, std::string req_to, std::string req_from = "auto") {
        myurl = "http://api.fanyi.baidu.com/api/trans/vip/translate?";
        appid = "*********";             //你的App Id
        secret_key = "*********";         //你的秘钥
        q = req_q;
        to = req_to;
        from = req_from;

        GetNewSalt();
        GetSignMd5();
        SetMyUrl();
    }

private:
    string myurl;
    string appid;
    string secret_key;
    string sign;
    string md5_sign;
    string q_encode;
    string salt;
public:
    string q;
    string from;
    string to;
    string send_myurl;
};

size_t processRecv(void* buffer, size_t size, size_t nmemb, void* userp);
int processInputString(int argc, char** argv, std::string& need_string, std::string& output_lang);
int resultSize(const std::string& res_src, const std::string& res_dst, std::string& final_result, std::string& fromto);
int ReallZhSize(const std::string& res_str);
int ProcessUpper(std::string& upper, int size);
int ProcessResult(std::string& result, const std::string& src, const std::string& dst, int max_size,int size_src, int size_dst);
std::string ProcessFinal(int max_size, const std::string& res_src, const std::string&res_dst, int size_src, int size_dst, std::string& fromto);
bool CheckSpecialChar(const char& check_char);
